package models

import (
	"GoTime/response"
	"GoTime/utils"
	"encoding/json"
	"errors"
	"fmt"
	"log"
	"strings"
	"time"

	"github.com/spf13/cast"
	"xorm.io/builder"
)

type Student struct {
	Id               int64     `xorm:"not null pk autoincr comment('自增主键') INT(11)"`
	UserId           int       `xorm:"not null comment('用户id外键关联dts_user中的id') index INT(11)"`
	SchoolId         int       `form:"school_id" xorm:"not null comment('驾校id即dts_school中的id') index INT(11)"`
	IcId             int       `xorm:"default 0 comment('IC卡id,学员可以没有IC卡也可以拥有多张IC卡，当前为生效IC卡id') INT(11)"`
	FingerId         int       `xorm:"default 0 comment('指纹id，学员可以拥有多个指纹记录，当前为生效指纹id') INT(11)"`
	PortraitId       int       `xorm:"default 0 comment('头像id，学员可以拥有多个头像记录，当前为生效头像id') INT(11)"`
	LicenceNumber    string    `xorm:"default '' comment('驾驶证号') VARCHAR(32)" form:"licence_number"`
	LicenceGrantDate time.Time `xorm:"comment('驾驶证初领日期 YYYYMMDD') DATE"`
	SignInTime       time.Time `xorm:"not null comment('报名时间 YYYYMMDD') index DATE"`
	OperationStatus  string    `xorm:"default '0' comment('业务类型 0:初领 1:增领 9:其他') ENUM('0','1','9')" form:"operation_status"`
	DrivingCarType   string    `xorm:"default 'C1' comment('原准驾车型') ENUM('A1','A2','A3','B1','B2','C1','C2','C3','C4','C5','D','E','F','M','N','P')" form:"driving_car_type"`
	TrainingCarType  string    `xorm:"default 'C1' comment('培训车型') ENUM('A1','A2','A3','B1','B2','C1','C2','C3','C4','C5','D','E','F','M','N','P')" form:"training_car_type"`
	Status           string    `xorm:"default '0' comment('学员学习进度状态，0：已报名，1234：科目一二三四，5：停止练车（处罚）,6：已结业') ENUM('0','1','2','3','4','5','6')" form:"status"`
	ApprovalStatus   string    `xorm:"default '0' comment('学员提交运管审核状态，0:待审核，1:通过审核，2:未通过审核') ENUM('0','1','2')" form:"approval_status"`
	RecordStatus     string    `xorm:"not null default '0' comment('备案状态 0:未备案 1:已备案') ENUM('0','1')"`
	InstitutionCode  string    `xorm:"comment('运管统一编号') index VARCHAR(16)"`
	LoginStatus      string    `xorm:"default '0' comment('0:登出状态  1：登录状态') ENUM('0','1')"`
	AcrossRecord     string    `xorm:"comment('0:正常    1：跨培训机构备案') ENUM('0','1')"`
	TotalMoney       int       `xorm:"not null default 0 comment('总缴费') INT(11)"`
	PayMoney         int       `xorm:"default 0 comment('已经交费') INT(11)"`
	PayStatus        int       `xorm:"default 0 comment('缴费状态0-未交费1-缴费未全2-已缴费') INT(11)"`
	CharstandardId   int       `xorm:"not null default 0 comment('收费方式id') INT(11)"`
	Frozentime       time.Time `xorm:"comment('冻结时间（用于重复消单的）') DATETIME"`
	Unfrozentime     time.Time `xorm:"comment('解冻时间（用于重复消单的）') DATETIME"`
	CoachId          int       `xorm:"not null default 0 comment('关联coach表id教练表id') index INT(11)"`
	Remainhours1     int64     `xorm:"default 0 comment('该学员剩余可练科目一学时') INT(11)"`
	Remainhours2     int64     `xorm:"default 0 comment('该学员剩余可练科目二学时') INT(11)"`
	Remainhours3     int64     `xorm:"default 0 comment('该学员剩余可练科目三学时') INT(11)"`
	Remainhours4     int64     `xorm:"default 0 comment('该学员剩余可练科目四学时') INT(11)"`
	Remark           string    `xorm:"VARCHAR(255)"`
	Isused           string    `xorm:"default '1' comment('0  已删除 1在使用') ENUM('0','1')"`
	Addtime          time.Time `xorm:"DATETIME created"`
	Reason           string    `xorm:"comment('审核未通过的原因') MEDIUMTEXT"`
	Subject1isreport string    `xorm:"default '0' comment('阶段学时第一部分是否上报') ENUM('0','1')"`
	Subject2isreport string    `xorm:"default '0' comment('阶段学时2是否上报') ENUM('0','1')"`
	Subject3isreport string    `xorm:"default '0' comment('阶段学时3是否上报') ENUM('0','1')"`
	Subject4isreport string    `xorm:"default '0' comment('阶段学时4是否上报') ENUM('0','1')"`
	Portrait_code    string    `xorm:"-"`
	Finger_code      string    `xorm:"-"`
	Portrait_url     string    `xorm:"-"`
	Finger_url       string    `xorm:"-"`
	Content          string    `xorm:"-"`
	Fileid           string    `xorm:"-"`
	PdfUrl           string    `xorm:"varchar(255) default('') " form:"pdf_url"`
	IsImport         int       `xorm:"default(0) comment('是否导入车学堂0未导入1已导入')"`
	CompleteCode     string    `xorm:"varchar(30)"`
	Istransfer       string    `xorm:""  form:"istransfer"`
	Sid              string    `xorm:"varchar(64)"`
}

// GetStudentList 获取学员列表
func (s *Student) GetStudentList(schoolId string, filter builder.Cond, offset, pageSize int) (count int64, studentList []response.StudentListResponse, err error) {
	err = engine.Table("dts_student").Alias("st").
		Select("st.id,u.name,u.phone,u.id_number,st.training_car_type,st.record_status,st.institution_code,st.istransfer,st.sid,st.login_status,st.operation_status,st.sign_in_time,st.addtime").
		Join("LEFT", []string{"dts_user", "u"}, "st.user_id = u.id").
		Where("st.school_id = ? and st.isused = ?", schoolId, "1").And(filter).
		Limit(pageSize, offset).
		Find(&studentList)
	count, err = engine.Table("dts_student").Alias("st").
		Select("COUNT(st.id)").
		Join("LEFT", []string{"dts_user", "u"}, "st.user_id = u.id").
		Where("st.school_id = ? and st.isused = ?", schoolId, "1").And(filter).
		Count()
	return
}

func (s *Student) GetInstitution(schoolCode string, user *User, photo, finger, province, city string) (student *Student, err error) {
	var (
		url    string
		retMap map[string]interface{}
	)
	data := map[string]interface{}{
		"inscode":     schoolCode,                                  //培训机构编号
		"cardtype":    user.IdType,                                 //证件类型
		"idcard":      strings.Replace(user.IdNumber, "t", "", -1), //证件号
		"nationality": user.Nationality,                            //国籍
		"name":        user.Name,                                   //姓名
		"sex":         user.Sex,                                    //性别
		"phone":       strings.Replace(user.Phone, "t", "", -1),    //手机号码
		"address":     user.Address,                                //联系地址
		"photo":       photo,                                       //照片文件ID
		"busitype":    s.OperationStatus,                           //业务类型
		"traintype":   s.TrainingCarType,                           //培训车型
		"applydate":   s.SignInTime.Format("20060102"),             //报名时间
	}
	if s.OperationStatus == "1" || s.OperationStatus == "12" {
		data["drilicnum"] = s.LicenceNumber                           //驾驶证号
		data["fstdrilicdate"] = s.LicenceGrantDate.Format("20060102") //驾驶证初领日期
		data["perdritype"] = s.DrivingCarType                         //原准驾车型
	}
	data["isotherprovince"] = user.Isotherprovince
	if s.OperationStatus == "11" || s.OperationStatus == "12" {
		if city != "130100" {
			data["birthday"] = user.Birthday
			data["icaddress"] = user.Icaddress
		}
	} else {
		if province == "510000" {
			data["birthday"] = user.Birthday
			data["icaddress"] = user.Icaddress
		}
	}
	if province != "370000" {
		data["fingerprint"] = finger
	}
	if url, err = utils.GetSignURL("student", data, 1, province, city); err != nil {
		return s, err
	}
	log.Println(url)
	param, _ := json.Marshal(data)
	var api_log ApiLog
	api_log.Url = url
	api_log.Param = string(param)
	api_log.Method = "POST"
	api_log.Time = time.Now()
	//请求运管
	if retMap, err = utils.APIReq(url, data, "POST"); err != nil {
		result, _ := json.Marshal(retMap)
		api_log.Result = string(result)
		api_log.Add()
		return s, err
	}
	result, _ := json.Marshal(retMap)
	api_log.Result = string(result)
	api_log.Add()
	fmt.Println(retMap)
	fmt.Println(retMap, "========,获取统一编号")
	if cast.ToInt(retMap["errorcode"]) != 0 {
		return s, errors.New(retMap["message"].(string))
	}
	if md, ok := retMap["data"].(map[string]interface{}); ok {
		s.InstitutionCode = fmt.Sprint(md["stunum"])
		return s, nil
	}
	return s, errors.New("获取学员编号失败")
}

func (s *Student) GetStudentById(id string) (ok bool, student *Student, err error) {
	student = new(Student)
	ok, err = engine.Table("dts_student").Select("*").
		Where("id = ? and isused = ?", id, "1").
		Get(student)
	log.Println(err, ok)
	return
}

func (s *Student) Edit(fields ...string) bool {
	var (
		err error
	)
	_, err = engine.ID(s.Id).Cols(fields...).Update(s)
	if err != nil {
		fmt.Println(err.Error())
		return false
	}
	return true
}

func (s *Student) RecordStudent(institution_code string, user *User, province, photo, finger_code, image_url, city, drilicimg string) (err error) {
	var (
		urls     string
		ret_map  map[string]interface{}
		req_type int64
	)
	if city == "130100" {
		req_type = 3
	} else {
		req_type = 2
	}
	data := map[string]interface{}{
		"inscode":     institution_code,                            //培训机构编号
		"stunum":      s.InstitutionCode,                           //学员编号
		"cardtype":    user.IdType,                                 //证件类型
		"idcard":      strings.Replace(user.IdNumber, "t", "", -1), //证件号
		"nationality": user.Nationality,                            //国籍
		"name":        user.Name,                                   //姓名
		"sex":         user.Sex,                                    //性别
		"phone":       strings.Replace(user.Phone, "t", "", -1),    //手机号码
		"address":     user.Address,                                //联系地址
		"busitype":    s.OperationStatus,                           //业务类型
		"traintype":   s.TrainingCarType,                           //培训车型
		"applydate":   s.SignInTime.Format("20060102"),             //报名时间
	}
	data["isotherprovince"] = user.Isotherprovince
	if s.OperationStatus == "1" || s.OperationStatus == "11" || s.OperationStatus == "12" { //增领，货运初领，货运增领，都需要传驾驶证号
		data["drilicnum"] = s.LicenceNumber                           //驾驶证号
		data["fstdrilicdate"] = s.LicenceGrantDate.Format("20060102") //驾驶证初领日期
		data["perdritype"] = s.DrivingCarType                         //原准驾车型
		data["drilicenceurl"] = drilicimg
		if city != "130100" {
			data["birthday"] = user.Birthday
			data["icaddress"] = user.Icaddress
		}
	}
	if province == "420000" {
		data["idcardfileurl"] = user.CardUrl
	}
	if province == "510000" {
		if s.OperationStatus == "0" || s.OperationStatus == "1" || s.OperationStatus == "11" || s.OperationStatus == "12" {
			data["birthday"] = strings.Replace(user.Birthday, "-", "", -1)
			data["icaddress"] = user.Icaddress
		}
	}
	//if city == "510100" { //四川省上传合同，如果没传编号，则通过pdf_url获取编号
	if s.PdfUrl == "" {
		return errors.New("电子合同不能为空")
	}
	if data["contractno"], err = utils.FileId(s.PdfUrl, "contractimg", req_type, province, city); err != nil {
		return err
	}
	//}
	// NOTE: 贵州省学员新增接口字段-是否签订合同
	if province == "520000" {
		data["iscontract"] = "1"
	}
	if province == "340000" {
		//if data["photo"], err = utils.AnHuiServiceFileID(image_url, "stuimg", req_type, province, city); err != nil {
		//	return err
		//}
	} else {
		if data["photo"], err = utils.FileId(image_url, "stuimg", req_type, province, city); err != nil {
			return err
		}
	}
	if s.OperationStatus != "0" {
		data["drilicnum"] = s.LicenceNumber
		data["fstdrilicdate"] = s.LicenceGrantDate.Format("20060102")
		data["perdritype"] = s.DrivingCarType
	}
	if urls, err = utils.GetSignURL("student", data, req_type, province, city); err != nil {
		return err
	}

	param, err := json.Marshal(data)
	if err != nil {
		fmt.Println("json.Marshal failed:", err)
		return
	}
	var api_log ApiLog
	api_log.Url = urls
	api_log.Param = string(param)
	api_log.Method = "POST"
	api_log.Time = time.Now()
	if ret_map, err = utils.APIReq(urls, data, "POST"); err != nil {
		result, _ := json.Marshal(ret_map)
		api_log.Result = string(result)
		api_log.Add()
		return err
	}
	result, _ := json.Marshal(ret_map)
	api_log.Result = string(result)
	api_log.Add()
	switch ret_map["errorcode"].(type) {
	case float64:
		if ret_map["errorcode"].(float64) != 0 {
			return errors.New(ret_map["message"].(string))
		}
	case string:
		if ret_map["errorcode"].(string) != "0" {
			return errors.New(ret_map["message"].(string))
		}
	}
	return nil
}
